package com.ruoyi.erecord.vehicles.service.impl;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.api.dto.equipment.EquipmentImageDetailDto;
import com.ruoyi.api.dto.equipment.EquipmentMapStatDto;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.tools.constant.ERecordConstant;
import com.ruoyi.common.tools.enums.DeviceTypeEnum;
import com.ruoyi.common.utils.BeanCopyUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.erecord.device.service.IDeviceService;
import com.ruoyi.erecord.vehicles.domain.Vehicles;
import com.ruoyi.erecord.vehicles.domain.bo.VehiclesBo;
import com.ruoyi.erecord.vehicles.domain.bo.VehiclesImportDetailBo;
import com.ruoyi.erecord.vehicles.domain.vo.VehiclesImportDetailVo;
import com.ruoyi.erecord.vehicles.domain.vo.VehiclesNameVo;
import com.ruoyi.erecord.vehicles.domain.vo.VehiclesVo;
import com.ruoyi.erecord.vehicles.mapper.VehiclesMapper;
import com.ruoyi.erecord.vehicles.service.IVehiclesImportDetailService;
import com.ruoyi.erecord.vehicles.service.IVehiclesService;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;

/**
 * 车辆Service业务层处理
 *
 * @author cc
 * @date 2023-04-17
 */
@RequiredArgsConstructor
@Service
public class VehiclesServiceImpl implements IVehiclesService {

	private final VehiclesMapper baseMapper;
	private final IVehiclesImportDetailService vehiclesImportDetailService;

	/**
	 * 查询车辆
	 */
	@Override
	public VehiclesVo queryById(Long id) {
		return baseMapper.selectVoById(id);
	}

	/**
	 * 查询车辆列表
	 */
	@Override
	public TableDataInfo<VehiclesVo> queryPageList(VehiclesBo bo, PageQuery pageQuery) {
		LambdaQueryWrapper<Vehicles> lqw = buildQueryWrapper(bo);
		Page<VehiclesVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
		return TableDataInfo.build(result);
	}

	/**
	 * 查询车辆列表
	 */
	@Override
	public List<VehiclesVo> queryList(VehiclesBo bo) {
		LambdaQueryWrapper<Vehicles> lqw = buildQueryWrapper(bo);
		return baseMapper.selectVoList(lqw);
	}

	private LambdaQueryWrapper<Vehicles> buildQueryWrapper(VehiclesBo bo) {
		Map<String, Object> params = bo.getParams();
		LambdaQueryWrapper<Vehicles> lqw = Wrappers.lambdaQuery();
		lqw.eq(StringUtils.isNotBlank(bo.getVehiclesCode()), Vehicles::getVehiclesCode, bo.getVehiclesCode());
		lqw.eq(bo.getDeptId() != null, Vehicles::getDeptId, bo.getDeptId());
		lqw.like(StringUtils.isNotBlank(bo.getVehiclesNumber()), Vehicles::getVehiclesNumber, bo.getVehiclesNumber());
		return lqw;
	}

	/**
	 * 新增车辆
	 */
	@Override
	public Boolean insertByBo(VehiclesBo bo) {
		Vehicles add = BeanUtil.toBean(bo, Vehicles.class);
		validEntityBeforeSave(add);
		boolean flag = baseMapper.insert(add) > 0;
		if (flag) {
			bo.setVehiclesCode(add.getVehiclesCode());
		}
		return flag;
	}

	/**
	 * 修改车辆
	 */
	@Override
	public Boolean updateByBo(VehiclesBo bo) {
		Vehicles update = BeanUtil.toBean(bo, Vehicles.class);
		validEntityBeforeSave(update);
		return baseMapper.updateById(update) > 0;
	}

	/**
	 * 保存前的数据校验
	 */
	private void validEntityBeforeSave(Vehicles entity) {
		// TODO 做一些数据校验,如唯一约束
		if (entity.getId() == null) {
			Long o = this.getVehiclesIdByNumber(entity.getVehiclesNumber());
			if (null != o) {
				throw new ServiceException("车牌号码 已经存在了！");
			}
			o = this.getVehiclesIdByCode(entity.getVehiclesCode());
			if (null != o) {
				throw new ServiceException("车牌编码 已经存在了！");
			}
		}
	}

	/**
	 * 批量删除车辆
	 */
	@Override
	public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
		if (isValid) {
			// TODO 做一些业务上的校验,判断是否需要校验
			for (Long id : ids) {
				if (((IDeviceService) SpringUtils.getBean(IDeviceService.class)).isUseById(DeviceTypeEnum.CAR,
						id)) {
					throw new ServiceException(StrUtil.format("车辆编码[ {} ] 被其他模块使用，不能删除！", this.getCodeById(id)));
				}
			}

		}
		return baseMapper.deleteBatchIds(ids) > 0;
	}

	@Override
	public Boolean batchInsertOrUpdate(String batchNo) {
		VehiclesImportDetailBo queryBo = new VehiclesImportDetailBo();
		queryBo.setBatchNo(batchNo);
		List<VehiclesImportDetailVo> detailList = this.vehiclesImportDetailService.queryList(queryBo);
		List<Vehicles> list = BeanCopyUtils.copyList(detailList, Vehicles.class);
		list.forEach(e -> {
			e.restBase();
			e.setId(this.getVehiclesIdByNumber(e.getVehiclesNumber()));
		});
		return this.baseMapper.insertOrUpdateBatch(list);
	}

	@Override
	public Boolean batchUpdate(List<VehiclesImportDetailVo> voList) {
		List<Vehicles> list = BeanCopyUtils.copyList(voList, Vehicles.class);
		list.forEach(e -> {
			e.restBase();
			e.setId(this.getVehiclesIdByNumber(e.getVehiclesNumber()));
		});
		return this.baseMapper.updateBatchById(list);
	}

	@Override
	public String getVehiclesNumberById(Long id) {
		if (null == id)
			return null;
		Vehicles o = this.baseMapper.selectById(id);
		if (null != o) {
			return o.getVehiclesNumber();
		}
		return null;
	}

	@Override
	public Long getVehiclesIdByNumber(String number) {
		LambdaQueryWrapper<Vehicles> lqw = Wrappers.lambdaQuery();
		lqw.eq(Vehicles::getVehiclesNumber, number);
		lqw.last("limit 1");
		Vehicles o = this.baseMapper.selectOne(lqw);
		if (null != o) {
			return o.getId();
		}
		return null;
	}

	@Override
	public boolean isUseEmployeeId(Long employeeId) {
		LambdaQueryWrapper<Vehicles> lqw = Wrappers.lambdaQuery();
		lqw.eq(Vehicles::getEmployeeCode, employeeId);
		return this.baseMapper.exists(lqw);
	}

	@Override
	public List<VehiclesNameVo> getVehiclesNameVoList(String vehiclesNumber) {
		VehiclesBo bo = new VehiclesBo();
		bo.setVehiclesNumber(vehiclesNumber);
		LambdaQueryWrapper<Vehicles> lqw = buildQueryWrapper(bo);
		lqw.last("limit 10");
		List<Vehicles> eList = baseMapper.selectList(lqw);
		List<VehiclesNameVo> list = BeanCopyUtils.copyList(eList, VehiclesNameVo.class);
		return list;
	}

	public Long getVehiclesIdByCode(String code) {
		LambdaQueryWrapper<Vehicles> lqw = Wrappers.lambdaQuery();
		lqw.eq(Vehicles::getVehiclesCode, code);
		lqw.last("limit 1");
		Vehicles o = this.baseMapper.selectOne(lqw);
		if (null != o) {
			return o.getId();
		}
		return null;
	}

	@Override
	public List<EquipmentImageDetailDto> getEquipmentImageDetailDtoList() {
		LambdaQueryWrapper<Vehicles> lqw = Wrappers.lambdaQuery();
		lqw.isNotNull(Vehicles::getFrontPic);
		List<Vehicles> vList = this.baseMapper.selectList(lqw);
		if (null == vList || vList.isEmpty()) {
			vList = this.baseMapper.selectList();
		}
		List<EquipmentImageDetailDto> list = vList.stream().map(v -> {
			EquipmentImageDetailDto dto = new EquipmentImageDetailDto();
			dto.setId(v.getId());
			dto.setPic1(v.getFrontPic());
			if (StrUtil.isEmpty(dto.getPic1())) {
				dto.setPic1(ERecordConstant.DEFAULT_PIC_OSS_ID);
			}
			return dto;
		}).collect(Collectors.toList());
		return list;
	}

	@Override
	public List<EquipmentMapStatDto> getEquipmentMapStatDtoList(Integer serviceTypeId, String date) {
		LambdaQueryWrapper<Vehicles> lqw = Wrappers.lambdaQuery();
		lqw.eq(Vehicles::getServiceType, serviceTypeId);
		List<Vehicles> vList = this.baseMapper.selectList(lqw);
		List<EquipmentMapStatDto> list = vList.stream().map(v -> {
			EquipmentMapStatDto dto = new EquipmentMapStatDto();
			dto.setId(v.getId());
			dto.setName(v.getVehiclesName());
			dto.setSerialNum(v.getVehiclesCode());
			dto.setServiceTypeId(v.getServiceType());
			dto.setUserId(v.getEmployeeCode());
			return dto;
		}).collect(Collectors.toList());
		return list;
	}

	private String getCodeById(Long id) {
		Vehicles obj = this.baseMapper.selectById(id);
		if (null != obj) {
			return obj.getVehiclesCode();
		}
		return null;
	}
}
